package com.shanzmoo.core.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.CharacterConstant;
import com.shanzmoo.base.constant.Constant;
import com.shanzmoo.base.constant.DeliveryBillOrderType;
import com.shanzmoo.base.constant.PayStatusConstant;
import com.shanzmoo.base.constant.e.PayTypeEnum;
import com.shanzmoo.base.constant.e.StoreDeliveryBillTypeEnum;
import com.shanzmoo.base.exception.OutletOrderException;
import com.shanzmoo.base.util.BillNoUtils;
import com.shanzmoo.base.util.MoneyUtils;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.config.pay.PayServiceConfig;
import com.shanzmoo.core.constant.OutletOrderStatusConstant;
import com.shanzmoo.core.domain.OutletOrderSaveDto;
import com.shanzmoo.core.domain.FactoryOrderSaveDto;
import com.shanzmoo.core.manager.store.StoreDeliveryBillManager;
import com.shanzmoo.db.order.entity.OutletOrderDetailEntity;
import com.shanzmoo.db.order.entity.OutletOrderEntity;
import com.shanzmoo.db.order.entity.bo.OrderDetailSkuBO;
import com.shanzmoo.db.order.entity.bo.PayMoneyResultBO;
import com.shanzmoo.db.order.entity.dto.*;
import com.shanzmoo.db.order.entity.vo.OutletOrderInfoVo;
import com.shanzmoo.db.order.entity.vo.OutletOrderLogVo;
import com.shanzmoo.db.order.entity.vo.OutletOrderPageVo;
import com.shanzmoo.db.order.service.IOutletOrderDetailService;
import com.shanzmoo.db.order.service.IOutletOrderService;
import com.shanzmoo.db.personnel.entity.MemberInfoEntity;
import com.shanzmoo.db.personnel.service.IMemberInfoService;
import com.shanzmoo.db.product.entity.vo.SkuResultVO;
import com.shanzmoo.db.product.service.IProductSkuService;
import com.shanzmoo.db.report.entity.vo.ProductSalesVO;
import com.shanzmoo.db.store.mapper.StoreDeliveryBillMapper;
import com.shanzmoo.db.trade.entity.PayOrderEntity;
import com.shanzmoo.core.domain.pay.PayOrderEntityLocalUtil;
import com.shanzmoo.core.domain.pay.PayResultResp;
import com.shanzmoo.db.trade.service.IPayOrderBodyService;
import com.shanzmoo.db.trade.service.IPayOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 *
 * @author： Gzhao 2021/1/31
 */
@Slf4j
@Component
public class OutletOrderManager {

    @Autowired
    private IOutletOrderService outletOrderService;
    @Autowired
    private IOutletOrderDetailService outletOrderDetailService;
    @Autowired
    private IMemberInfoService memberInfoService;
    @Autowired
    private FactoryOrderMananger factoryOrderMananger;
    @Autowired
    private DeliveryManager deliveryManager;
    @Autowired
    private IProductSkuService productSkuService;
    @Autowired
    private PayServiceConfig payServiceConfig;
    @Autowired
    private IPayOrderService payOrderService;
    @Autowired
    private IPayOrderBodyService payOrderBodyService;
    @Autowired
    private OutletOrderLogManager outletOrderLogManager;
    @Autowired
    private StoreDeliveryBillManager storeDeliveryBillManager;

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> add(OutletOrderSaveDto saveDto) {

        // 1. 生成订单号
        String orderNo = BillNoUtils.generateOutletOrderNo(CurrentUserCache.getOutletMark());

        // 2. 校验价格：
        checkOrderMoney(saveDto);

        // 3. 保存订单信息
        this.saveOrder(saveDto, orderNo);

        return SResponse.ok(Boolean.TRUE);
    }

    public SResponse<PageRespBase<OutletOrderPageVo>> getPageList(OutletOrderQueryDto queryDto) {
        // 处理客户名称
        List<Integer> memberIds = null;
        if (StrUtil.isNotBlank(queryDto.getMemberName())) {
            List<MemberInfoEntity> memberList = memberInfoService.list(
                    new QueryWrapper<MemberInfoEntity>()
                            .eq("deleted", false)
                            .like("name", queryDto.getMemberName().trim())
            );
            if (CollectionUtil.isNotEmpty(memberList)) {
                memberIds = memberList.stream().map(MemberInfoEntity::getId).collect(Collectors.toList());
            }
        }

        // 开启分页
        Page page = PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());

        List<OutletOrderEntity> list = outletOrderService.list(
                new QueryWrapper<OutletOrderEntity>()
                        .eq("deleted", false)
                        .like(StrUtil.isNotBlank(queryDto.getOrderNo()), "order_no", queryDto.getOrderNo())
                        .like(StrUtil.isNotBlank(queryDto.getConsigneeMobile()), "consignee_mobile", queryDto.getConsigneeMobile())
                        .in(CollectionUtil.isNotEmpty(memberIds), "id", memberIds)
                        .eq(CurrentUserCache.getOutletId() > 0, "outlet_id", CurrentUserCache.getOutletId())
                        .orderByDesc("create_time")
        );
        // 返回结果
        List<OutletOrderPageVo> reList;

        List<Integer> orderMemberIds = list.stream().map(OutletOrderEntity::getMemberId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(orderMemberIds)) {
            List<MemberInfoEntity> orderMemberList = memberInfoService.list(
                    new QueryWrapper<MemberInfoEntity>()
                            .eq("deleted", false)
                            .in("id", orderMemberIds)
            );

            reList = list.stream().map(e -> {
                return OutletOrderPageVo.create(e, orderMemberList);
            }).collect(Collectors.toList());

        } else {
            reList = Collections.emptyList();
        }

        PageRespBase<OutletOrderPageVo> re = PageRespBase.create(page, reList);
        PageHelper.clearPage();
        return SResponse.ok(re);
    }

    public SResponse<OutletOrderInfoVo> getInfo(String orderNo) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(orderNo);

        List<OutletOrderDetailEntity> detailList = outletOrderDetailService.list(
                new QueryWrapper<OutletOrderDetailEntity>()
                        .eq("deleted", false)
                        .eq("order_no", orderNo)
        );
        OutletOrderInfoVo orderInfoVo = OutletOrderInfoVo.create(order, detailList);

        MemberInfoEntity member = memberInfoService.getById(orderInfoVo.getMemberId());
        orderInfoVo.setMemberName(member.getName());

        if (StrUtil.isNotEmpty(orderInfoVo.getPayNo())){
            PayOrderEntity payOrder = payOrderService.getByPayNo(orderInfoVo.getPayNo());
            orderInfoVo.setPayFinishTime(payOrder.getFinishTime());
            orderInfoVo.setPayType((payOrder.getType().equals(PayTypeEnum.Wx.getCode()))  ? "微信" : "支付宝");
        } else {
            // 获取订单的最新支付情况
            List<PayOrderEntity> payOrderList = payOrderService.list(
                    new QueryWrapper<PayOrderEntity>()
                            .eq("deleted", false)
                            .eq("status", true)
                            .eq("order_no", orderNo)
                            .orderByDesc("pay_status")
            );

            for(PayOrderEntity payOrder : payOrderList){

                if (payOrder.getPayStatus() == PayStatusConstant.PAY_SUCCESS) {
                    updatePayInfo(order.getId(), payOrder.getPayNo());
                    orderInfoVo.setPayFinishTime(payOrder.getFinishTime());
                    orderInfoVo.setPayType((payOrder.getType().equals(PayTypeEnum.Wx.getCode()))  ? "微信" : "支付宝");
                    orderInfoVo.setPayNo(payOrder.getPayNo());
                    orderInfoVo.setPayStatus(true);

                    break;
                }
                if (payOrder.getPayStatus().equals(PayStatusConstant.PAY_Fail)) {
                    continue;
                }
                PayOrderEntityLocalUtil.setPayOrder(payOrder, payOrderBodyService.getByPayNo(payOrder.getPayNo()));

                // 请求支付api 获取支付结果
                SResponse<PayResultResp> re = payServiceConfig
                        .getPayService(EnumUtil.likeValueOf(PayTypeEnum.class, payOrder.getType()))
                        .queryPayResult(payOrder.getPayNo());

                if (re.isOk() && re.getData().isSuccess()){
                    // 更新支付单信息
                    PayOrderEntityLocalUtil.setReqBody(null);
                    PayOrderEntityLocalUtil.setRespBody(null);
                    payOrderService.updateByPayQuery(payOrder, PayOrderEntityLocalUtil.getPayOrderBodyEntity());

                    updatePayInfo(payOrder.getId(), payOrder.getPayNo());
                    orderInfoVo.setPayFinishTime(payOrder.getFinishTime());
                    orderInfoVo.setPayType((payOrder.getType().equals(PayTypeEnum.Wx.getCode()))  ? "微信" : "支付宝");
                    orderInfoVo.setPayNo(payOrder.getPayNo());
                    orderInfoVo.setPayStatus(true);

                    break;
                }
            }
        }

        return SResponse.ok(orderInfoVo);
    }

    public SResponse<List<OutletOrderDetailInfoDto>> getInfoDeatils(String orderNo) {

        List<OutletOrderDetailEntity> detailList = outletOrderDetailService.list(
                new QueryWrapper<OutletOrderDetailEntity>()
                        .eq("deleted", false)
                        .eq("order_no", orderNo)
        );

        return SResponse.ok(OutletOrderDetailInfoDto.createList(detailList));
    }

    public SResponse<List<OutletOrderDetailInfoDto>> getWaitAllotDetail(String orderNo) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(orderNo);
        if (!order.getRoot()) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "当前订单不是刷机订单");
        }
        List<OutletOrderDetailEntity> detailList = outletOrderDetailService.list(
                new QueryWrapper<OutletOrderDetailEntity>()
                        .eq("deleted", false)
                        .eq("order_no", orderNo)
                        .eq("root", true)
        );

        outletOrderLogManager.saveLog(order.getId(), "分配订单");
        return SResponse.ok(OutletOrderDetailInfoDto.createList(detailList));
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> confirmAllot(FactoryOrderSaveDto saveDto) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(saveDto.getOrderNo());

        // 生成生产单
        factoryOrderMananger.saveOrder(saveDto, order.getMemberId());

        // 校验生产单的商品数量
        factoryOrderMananger.checkSkuNumByOrder(order.getOrderNo());

        // 修改订单状态
        OutletOrderEntity updateOrderInfo = OutletOrderEntity.builder()
                .id(order.getId())
                .status(OutletOrderStatusConstant.ROOTING)
                .updateUser(CurrentUserCache.getUserId())
                .build();
        outletOrderService.updateById(updateOrderInfo);
        return SResponse.ok(Boolean.TRUE);
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> cancelOrder(OutletOrderCancelDto cancelDto) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(cancelDto.getOrderNo());

        if (order.getPayStatus()) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "订单已支付，不允许作废");

        } else if (order.getStatus() == OutletOrderStatusConstant.TASK_FINISH || order.getStatus() == OutletOrderStatusConstant.FINANCE_FINISH
                || order.getStatus() == OutletOrderStatusConstant.CANCEL) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "当前订单状态，不允许作废");

        } else if (order.getRoot() && order.getStatus() != OutletOrderStatusConstant.NEW) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "订单已分配，请取消生产单后再作废");

        }

        OutletOrderEntity updateOrder = OutletOrderEntity.builder()
                .id(order.getId())
                .status(OutletOrderStatusConstant.CANCEL)
                .cancelReason(cancelDto.getCancelReason())
                .updateUser(CurrentUserCache.getUserId())
                .build();

        outletOrderService.updateById(updateOrder);

        outletOrderLogManager.saveLog(order.getId(), "作废订单");
        return SResponse.ok(Boolean.TRUE);
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> financeFinish(OutletOrderFinanceFinishDto financeFinishDto) {
        List<String> orderNoList = financeFinishDto.getOrderNoList();
        for (String orderNo : orderNoList) {
            OutletOrderEntity order = this.obtainSelfOrderByNo(orderNo);
            if (order.getStatus() != OutletOrderStatusConstant.TASK_FINISH) {
                return SResponse.fail(Constant.ERRCODE_LOGIC, "订单:" + orderNo + "未完成，结算失败");
            }

            OutletOrderEntity updateOrder = OutletOrderEntity.builder()
                    .id(order.getId())
                    .status(OutletOrderStatusConstant.FINANCE_FINISH)
                    .updateUser(CurrentUserCache.getUserId())
                    .build();

            outletOrderService.updateById(updateOrder);

            outletOrderLogManager.saveLog(order.getId(), "订单结算");
        }
        return SResponse.ok(Boolean.TRUE);
    }

    @PreAuthorize("!hasAnyAuthority('admin')")
    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> selfDeliver(String orderNo) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(orderNo);
        if (order.getStatus() != 2) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "请选择“待取货”订单发货");
        }

        // 1.生成发货单
        List<OutletOrderDetailEntity> detailList = outletOrderDetailService.getDetailByOrderNo(order.getOrderNo());
        deliveryManager.generateSlefBill(order, detailList, DeliveryBillOrderType.OUTLET);

        // 2.修改订单状态
        OutletOrderEntity orderUpdate = OutletOrderEntity.builder()
                .id(order.getId())
                .status(OutletOrderStatusConstant.TASK_FINISH)
                .build();
        outletOrderService.updateById(orderUpdate);

        outletOrderLogManager.saveLog(order.getId(), "自提发货");
        return SResponse.ok(Boolean.TRUE);
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> createDeliverBill(String orderNo) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(orderNo);
        if (order.getStatus() != 2) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "请选择“待取货”订单");
        }
        Boolean bool = storeDeliveryBillManager.createBill(order.getOrderNo(), StoreDeliveryBillTypeEnum.OUTLET_ORDER,
                order.getMemberId(), order.getOutletId());
        return SResponse.ok(bool);
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> logisticsDeliver(LogisticsDeliverDto deliverDto) {
        OutletOrderEntity order = this.obtainSelfOrderByNo(deliverDto.getOrderNo());
        if (order.getStatus() != OutletOrderStatusConstant.WAIT_TAKE) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, "请选择“待取货”订单发货");
        }

        // 1.生成发货单
        deliveryManager.generateLogisticsBill(deliverDto, DeliveryBillOrderType.OUTLET);

        // 2.判断订单是否发货完成
        boolean deliveryOver = true;
        String checkStr = outletOrderService.checkDeliveryOver(order.getOrderNo());
        if (StrUtil.isNotBlank(checkStr) && checkStr.contains(CharacterConstant.ZERO_STRING)) {
            deliveryOver = false;
        }

        // 3.若发货完成，修改订单状态
        if (deliveryOver) {
            OutletOrderEntity orderUpdate = OutletOrderEntity.builder()
                    .id(order.getId())
                    .status(OutletOrderStatusConstant.TASK_FINISH)
                    .build();
            outletOrderService.updateById(orderUpdate);
        }

        outletOrderLogManager.saveLog(order.getId(), "物流发货");
        return SResponse.ok(Boolean.TRUE);
    }

    /**
     * 根据订单号，门店id 查询订单，防止查询到其他门店订单
     *
     * @param orderNo
     * @return
     */
    public OutletOrderEntity obtainSelfOrderByNo(String orderNo) {
        OutletOrderEntity order = outletOrderService.getOne(
                new QueryWrapper<OutletOrderEntity>()
                        .eq("deleted", false)
                        .eq("order_no", orderNo)
                        .eq(CurrentUserCache.getOutletId() > 0, "outlet_id", CurrentUserCache.getOutletId())
        );
        if (order == null) {
            throw new OutletOrderException("未查询到订单");
        }
        return order;
    }

    public SResponse<List<OutletOrderDetailSaveDto>> obtainImportSkuList(MultipartFile file) {
        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<OrderDetailSkuBO> excelDataList = reader.readAll(OrderDetailSkuBO.class);

            // 标准商品集合
            List<OutletOrderDetailSaveDto> standardSkuList = new ArrayList<>();
            // 非标准商品集合
            List<OutletOrderDetailSaveDto> nonstandardSkuList = new ArrayList<>();

            for (int i = 0; i < excelDataList.size(); i++) {
                OrderDetailSkuBO skuBO = excelDataList.get(i);

                if (StrUtil.isNotEmpty(skuBO.getSkuNum())) {
                    OutletOrderDetailSaveDto orderDetailSaveDto = skuBO.convert(i + 1);

                    if (orderDetailSaveDto.getType()) {
                        standardSkuList.add(orderDetailSaveDto);
                    } else {
                        nonstandardSkuList.add(orderDetailSaveDto);
                    }
                }
            }
            // 更新标准sku信息
            if (CollectionUtil.isNotEmpty(standardSkuList)) {
                // 获取系统sku信息
                List<String> skuCodeList = standardSkuList.stream().filter(e -> e.getType())
                        .map(OutletOrderDetailSaveDto::getSku)
                        .collect(Collectors.toList());

                List<SkuResultVO> skuList = productSkuService.querySku(skuCodeList);

                for (OutletOrderDetailSaveDto outletOrderDetailSaveDto : standardSkuList) {
                    if (!outletOrderDetailSaveDto.getType()) {
                        continue;
                    }
                    List<SkuResultVO> skuTempList = skuList.stream()
                            .filter(e -> e.getSku().equals(outletOrderDetailSaveDto.getSku()))
                            .collect(Collectors.toList());
                    if (CollectionUtil.isEmpty(skuTempList)) {
                        return SResponse.fail(Constant.ERRCODE_LOGIC, "未在系统sku中匹配到商品：" + outletOrderDetailSaveDto.getSku());
                    }
                    outletOrderDetailSaveDto.fillAttribute(skuTempList.get(0));
                }
            }

            // 分组合并标准商品 sn码
            Map<String, List<OutletOrderDetailSaveDto>> groupMap = standardSkuList.stream().collect(Collectors.groupingBy(OutletOrderDetailSaveDto::getSku));
            // 分组后标准商品集合
            List<OutletOrderDetailSaveDto> standardSkuGroupList = new ArrayList<>(groupMap.size());
            for (String skuKey : groupMap.keySet()) {
                List<OutletOrderDetailSaveDto> groupTempList = groupMap.get(skuKey);
                int skuNum = groupTempList.stream().mapToInt(OutletOrderDetailSaveDto::getSkuNum).sum();
                String snCode = CollectionUtil.join(
                        groupTempList.stream().map(OutletOrderDetailSaveDto::getSnCode).collect(Collectors.toList()),
                        ",");

                OutletOrderDetailSaveDto standardSkuGroup = groupTempList.get(0);
                standardSkuGroup.setSkuNum(skuNum);
                standardSkuGroup.setSnCode(snCode);
                standardSkuGroupList.add(standardSkuGroup);
            }

            List<OutletOrderDetailSaveDto> resultList = CollectionUtil.addAllIfNotContains(standardSkuGroupList, nonstandardSkuList);
            return SResponse.ok(resultList);
        } catch (IOException e) {
            log.error("上传文件获取失败", e);
            return SResponse.fail(Constant.ERRCODE_LOGIC, "Excel文件获取失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<PayMoneyResultBO> payMoney(OrderPayDTO payDTO) {
        //支付订单
        PayOrderEntityLocalUtil.initOrder(obtainPayOrderInfo(payDTO));

        SResponse<PayMoneyResultBO> re = payServiceConfig.getPayService(payDTO.getPayType())
                .tradePay(payDTO.getPayCode());


        // 保存支付订单信息
        PayOrderEntity payOrder = payOrderService.saveOrder(PayOrderEntityLocalUtil.getPayOrderEntity(), PayOrderEntityLocalUtil.getPayOrderBodyEntity());
        PayOrderEntityLocalUtil.clear();

        OutletOrderEntity order = this.obtainSelfOrderByNo(payOrder.getOrderNo());

        outletOrderLogManager.saveLog(order.getId(), "订单收款");
        return re;
    }

    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> queryOrderPayResult(String orderNo) {
        OutletOrderEntity outletOrder = this.obtainSelfOrderByNo(orderNo);
        if (outletOrder.getPayStatus()){
            return SResponse.ok(Boolean.TRUE);
        }
        List<PayOrderEntity> payOrderList = payOrderService.list(
                new QueryWrapper<PayOrderEntity>()
                        .eq("deleted", false)
                        .eq("status", true)
                        .eq("order_no", orderNo)
                        .orderByDesc("pay_status")
        );

        for(PayOrderEntity payOrder : payOrderList){

            if (payOrder.getPayStatus() == PayStatusConstant.PAY_SUCCESS) {
                updatePayInfo(outletOrder.getId(), payOrder.getPayNo());
                return SResponse.ok(Boolean.TRUE);
            }
            if (payOrder.getPayStatus() == PayStatusConstant.PAY_Fail) {
                continue;
            }
            PayOrderEntityLocalUtil.setPayOrder(payOrder, payOrderBodyService.getByPayNo(payOrder.getPayNo()));

            // 请求支付api 获取支付结果
            SResponse<PayResultResp> re = payServiceConfig
                    .getPayService(EnumUtil.likeValueOf(PayTypeEnum.class, payOrder.getType()))
                    .queryPayResult(payOrder.getPayNo());

            if (re.isOk() && re.getData().isSuccess()){
                // 更新支付单信息
                PayOrderEntityLocalUtil.setReqBody(null);
                PayOrderEntityLocalUtil.setRespBody(null);
                payOrderService.updateByPayQuery(payOrder, PayOrderEntityLocalUtil.getPayOrderBodyEntity());

                updatePayInfo(outletOrder.getId(), payOrder.getPayNo());
                return SResponse.ok(Boolean.TRUE);
            }
        }
        return SResponse.ok(Boolean.FALSE);
    }

    public List<OutletOrderLogVo> getLogList(Integer orderId) {
        return outletOrderLogManager.queryListByOrderId(orderId, CurrentUserCache.getOutletId());
    }

    public void updatePayStatus(String orderNo, String payNo) {
        OutletOrderEntity order = outletOrderService.getOne(
                new QueryWrapper<OutletOrderEntity>()
                        .eq("order_no", orderNo)
        );
        if (order != null){
            order.setPayNo(payNo);
            order.setPayStatus(true);

            outletOrderService.updateById(order);

            outletOrderLogManager.saveLog(order.getId(), "支付结果通知：支付成功");
        }
    }

    public List<ProductSalesVO> getProductSales() {
        return outletOrderService.getProductSales();
    }

    /**
     * 更新门店订单支付信息
     * @param orderId
     * @param payNo
     */
    private void updatePayInfo(Integer orderId, String payNo) {
        OutletOrderEntity outletOrder = new OutletOrderEntity();
        outletOrder.setId(orderId);
        outletOrder.setPayNo(payNo);
        outletOrder.setPayStatus(true);

        outletOrderService.updateById(outletOrder);
    }

    /**
     * 获取支付订单
     *
     * @param payDTO
     * @return
     * @author Gzhao 2021/1/9
     */
    private PayOrderEntity obtainPayOrderInfo(OrderPayDTO payDTO) {
        OutletOrderEntity orderEntity = this.obtainSelfOrderByNo(payDTO.getOrderNo());

        return PayOrderEntity.builder()
                .type(payDTO.getPayType().getCode())
                .payNo(BillNoUtils.generatePayNo())
                .orderNo(payDTO.getOrderNo())
                .payStatus(PayStatusConstant.WAIT_PAY)
                .body(CurrentUserCache.getOutletName() + " 订单 " + orderEntity.getOrderNo())
                .totalFee(MoneyUtils.changeToFen(orderEntity.getReceiveAmount()))
                .feeType("CNY")
                .ip(NetUtil.getLocalhostStr())
                .outletId(CurrentUserCache.getOutletId())
                .build();
    }

    private void saveOrder(OutletOrderSaveDto saveDto, String orderNo) {
        OutletOrderEntity outletOrder = saveDto.covert2OutletOrder(orderNo);
        List<OutletOrderDetailEntity> outletOrderDetailList = saveDto.covert2OutletOrderDetails(orderNo);

        judgeRootOrder(outletOrder, outletOrderDetailList);

        if (outletOrder.getId() != null){
            outletOrderService.updateById(outletOrder);
            outletOrderDetailService.deleteByOrderNo(outletOrder.getOrderNo());

            outletOrderLogManager.saveLog(outletOrder.getId(), "修改订单信息");
        } else {
            outletOrderService.save(outletOrder);

            outletOrderLogManager.saveLog(outletOrder.getId(), "新增订单");
        }
        outletOrderDetailService.saveBatch(outletOrderDetailList);


    }

    /**
     * 判断是否有刷机订单，如果不是刷机订单，订单状态直接为“待取货”
     *
     * @param outletOrder
     * @param outletOrderDetailList
     */
    private void judgeRootOrder(OutletOrderEntity outletOrder, List<OutletOrderDetailEntity> outletOrderDetailList) {

        boolean root = false;

        for (OutletOrderDetailEntity detailEntity : outletOrderDetailList) {
            if (detailEntity.getRoot()) {
                root = true;
                break;
            }
        }
        outletOrder.setRoot(root);
        if (!root) {
            outletOrder.setStatus(OutletOrderStatusConstant.WAIT_TAKE);
        } else {
            outletOrder.setStatus(OutletOrderStatusConstant.NEW);
        }
    }

    /**
     * 校验价格
     *
     * @param saveDto
     */
    private void checkOrderMoney(OutletOrderSaveDto saveDto) {
        // 1. 实付金额 = 订单金额 - 优惠金额 - 折扣金额
        BigDecimal amount = saveDto.getAmount();
        BigDecimal receiveAmount = saveDto.getReceiveAmount();
        BigDecimal abatement = saveDto.getAbatement();
        BigDecimal discountAmount = saveDto.getDiscountAmount();
        if (amount.subtract(receiveAmount).subtract(abatement).subtract(discountAmount).intValue() != 0) {
            throw new OutletOrderException("实付金额不等于订单金额减优惠金额");
        }

        // 2. 订单金额 = sum (商品总额)
        BigDecimal productTotalAmount = saveDto.getOrderDetails().stream().map(e -> e.getTotalPrice())
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (amount.subtract(productTotalAmount).intValue() != 0) {
            throw new OutletOrderException("订单金额与商品总金额不相等");
        }
    }
}
